/*
 * Copyright 2012-2013 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgettable.client.ui.grid.column;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.MenuItem;

import finbudgettable.client.ui.grid.ValueHolder;

public class CheckBoxMenuItem extends MenuItem implements ValueHolder.View {

    public interface ClickHandler {
        boolean onClick(boolean checked);
    }

    @Override
    public void refresh() {
        Element checkbox = Document.get().getElementById(checkboxId).cast();
        if (checkbox != null) {
            Element parent = checkbox.getParentElement().cast();
            parent.setInnerHTML(getHtml().asString());
        }
    }

    public static interface Template extends SafeHtmlTemplates {

    	@Template("<div id='{0}' checked='true'><img src='{2}' class='{3}'/><div class='{4}'>{1}</div></div>")
        SafeHtml checked(String id, String text, SafeUri imgUri, String imgClass, String labelClass);

    	@Template("<div id='{0}' checked='true' style='opacity:0.5'><img src='{2}' class='{3}'/><div class='{4}'>{1}</div></div>")
        SafeHtml checkedDisabled(String id, String text, SafeUri imgUri, String imgClass, String labelClass);

    	@Template("<div id='{0}'><div class='{2}'>{1}</div></div>")
        SafeHtml unchecked(String id, String text, String labelClass);

    	@Template("<div id='{0}' style='opacity:0.5'><div class='{2}'>{1}</div></div>")
        SafeHtml uncheckedDisabled(String id, String text, String labelClass);
    }

    private static final Template template = GWT.create(Template.class);

    private final ValueHolder<Boolean> holder;
    private final String caption;
    private final String checkboxId;
    private final ClickHandler clickHandler;

    public CheckBoxMenuItem(String caption, ValueHolder<Boolean> holder, ClickHandler clickHandler) {
        super(caption, (Command) null);
        this.holder = holder;
        this.clickHandler = clickHandler;
        this.checkboxId = DOM.createUniqueId();
        this.caption = caption;
        addStyleName(GridColumn.RESOURCES.style().bColumnMenuItem());
        setHTML(getHtml());
    }

    private SafeHtml getHtml() {
        if (holder.getValue()) {
            if (isEnabled()) {
            	return template.checked(checkboxId, caption, GridColumn.RESOURCES.checkmark().getSafeUri(), GridColumn.RESOURCES.style().checkmarkImg(), GridColumn.RESOURCES.style().checkmarkLabel());
            } else {
                return template.checkedDisabled(checkboxId, caption, GridColumn.RESOURCES.checkmark().getSafeUri(), GridColumn.RESOURCES.style().checkmarkImg(), GridColumn.RESOURCES.style().checkmarkLabel());
            }
        } else {
            if (isEnabled()) {
                return template.unchecked(checkboxId, caption, GridColumn.RESOURCES.style().checkmarkLabel());
            } else {
                return template.uncheckedDisabled(checkboxId, caption, GridColumn.RESOURCES.style().checkmarkLabel());
            }
        }
    }

    public void onBrowserEvent(Event event, Element parent) {
        String eventType = event.getType();
        if ("click".equals(eventType)) {
            if (isEnabled()) {
            	com.google.gwt.dom.client.Element div = parent.getFirstChildElement();
            	if (div != null) {
            		boolean checked = "true".equals(div.getAttribute("checked"));
            		if (clickHandler.onClick(!checked)) {
            			// In case the column is actually hidden (the last visible column is not hiding)
                		holder.setValue(!checked);
                		refresh();
            		}
            	}
            }
    		event.preventDefault();
        }
    }

    @Override
    public void setEnabled(boolean enabled) {
    	if (isEnabled() != enabled) {
    		super.setEnabled(enabled);
    		refresh();
    	}
    }

}
